import asyncio
from contextlib import asynccontextmanager
from typing import  Dict, Any, AsyncGenerator
import aio_pika
from minio import Minio
from socketio import AsyncServer
from core.config import settings
from core.logger import log
from services.redis_service import AsyncRedisService
from utils.sender_tools import SenderTools
from scheduler.msg_async_sch import MsgAsyncScheduler
# 全局单例实例
_rabbitmq_instance = None
_redis_service_instance = None
_scheduler_instance = None
_deep_seek_instance = None
_sender_tools_instance = None
_monitor_task_instance = None
_monitor_state_instance =  None
_minio_client = None
# 创建全局的 Socket.IO 实例
_sio = AsyncServer(
    async_mode='asgi',
    cors_allowed_origins="*"  # 处理跨域
)
_redis_service_lock = asyncio.Lock()
_rabbitmq_lock = asyncio.Lock()
async def init_rabbitmq():
    """初始化 RabbitMQ 连接和信道"""
    global _rabbitmq_instance
    async with _rabbitmq_lock:
        if _rabbitmq_instance is None or _rabbitmq_instance.is_closed:
            try:
                _rabbitmq_instance = await aio_pika.connect_robust(
                    host=settings.RABBITMQ_HOST,
                    port=settings.RABBITMQ_PORT,
                    login=settings.RABBITMQ_USERNAME,
                    password=settings.RABBITMQ_PASSWORD
                )
                log.info("RabbitMQ 创建连接成功")
            except Exception as e:
                log.info(f"RabbitMQ 连接初始化失败: {e}")
                raise
    return _rabbitmq_instance

async def get_rabbitmq() -> aio_pika.Connection:
    global _rabbitmq_instance
    if _rabbitmq_instance is None:
        _rabbitmq_instance = await init_rabbitmq()
    elif _rabbitmq_instance.is_closed:
        _rabbitmq_instance = await init_rabbitmq()
    return _rabbitmq_instance

@asynccontextmanager
async def get_rabbitmq_channel() -> AsyncGenerator[aio_pika.Channel, None]:
    """获取 RabbitMQ 信道的依赖"""
    rabbitmq_conn = await get_rabbitmq()
    channel = await rabbitmq_conn.channel()
    try:
        yield channel
    finally:
        if not channel.is_closed:
            await channel.close()

def get_minio_client():
    global _minio_client
    if _minio_client is None:
        _minio_client = Minio(settings.MINIO_ENDPOINT, settings.MINIO_ACCESS_KEY, settings.MINIO_SECRET_KEY, secure=False)
        return _minio_client
    return _minio_client

# 如果你有获取 sio 的依赖函数，应该这样定义：
def get_sio():
    return _sio

async def get_scheduler() -> MsgAsyncScheduler:
    global _scheduler_instance
    if _scheduler_instance is None:
        _scheduler_instance = MsgAsyncScheduler(monitoring_tasks=get_monitoring_tasks(), monitoring_states=get_monitoring_states(), sio=get_sio(), redis_service=await get_redis_service())
    return _scheduler_instance

async def get_redis_service():
    global _redis_service_instance
    if _redis_service_instance is None:
        async with _redis_service_lock:
            if _redis_service_instance is None:
                _redis_service_instance = AsyncRedisService()
                await _redis_service_instance.init_redis()
    return _redis_service_instance

def get_sender_tools() -> SenderTools:
    global _sender_tools_instance
    if _sender_tools_instance is None:
        _sender_tools_instance = SenderTools()
    return _sender_tools_instance

def get_monitoring_tasks() -> Dict[str, asyncio.Task]:
    global _monitor_task_instance
    if _monitor_task_instance is None:
        _monitor_task_instance = {}
    return _monitor_task_instance

def get_monitoring_states() -> Dict[str, Dict[str, Any]]:
    global _monitor_state_instance
    if _monitor_state_instance is None:
        _monitor_state_instance = {}
    return _monitor_state_instance